package com.zlkj.ssm.shop.web.freemarker.core;

import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.zlkj.ssm.shop.front.entity.News;
import com.zlkj.ssm.shop.front.entity.Product;
import com.zlkj.ssm.shop.front.service.NewsService;
import com.zlkj.ssm.shop.front.service.ProductService;
import com.zlkj.ssm.shop.web.tools.RequestHolder;

import javax.servlet.ServletContext;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * 生成模板的帮助类
 */
@Component
public class FreemarkerHelper {
	private static final Logger logger = LoggerFactory.getLogger(FreemarkerHelper.class);
	@Autowired
	private ProductService productService;
	@Autowired
	private NewsService newsService;

	/**
	 * 模板
	 */
	public static final String template_newsInfo = "newsInfo_.ftl";// 文章模板newsInfo.ftl
	public static final String template_product = "product.ftl";// 商品介绍模板

	public void setProductService(ProductService productService) {
		this.productService = productService;
	}

	public void setNewsService(NewsService newsService) {
		this.newsService = newsService;
	}

	/**
	 * 生成门户静态页面
	 * 
	 * @return
	 */
	// public void index(String template, String templateHtml) {
	// try {
	// // 准备数据
	// HashMap<String, Object> data = new HashMap<String, Object>();
	// data.put("indexMenuList", loadIndexMenu());
	// crateHTML(ServletActionContext.getServletContext(), data, template,
	// templateHtml);
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// }

	/**
	 * 加载门户菜单列表
	 * 
	 * @return
	 * @return
	 */
	// private List<IndexMenu> loadIndexMenu() {
	// IndexMenu e = new IndexMenu();
	// List<IndexMenu> indexMenuList = indexMenuService.selectList(e);
	// return indexMenuList;
	// }

	/**
	 * 生成静态页面主方法
	 * 
	 * @param context
	 * 
	 * @param data
	 *            数据 key - value
	 * @param name
	 *            ftl文件 存在 模板根目录路径下
	 * @param targetHtmlPath
	 *            要生成的静态文件的路径,相对设置中的根路径,例如 "jsp/user/1.html"
	 */
	public void crateHTML(ServletContext context, Map<String, Object> data, String name, String targetHtmlPath) throws Exception {
		if (StringUtils.isBlank(targetHtmlPath)) {
			throw new NullPointerException("targetHtmlPath不能为空！");
		}

		Configuration freemarkerCfg = new Configuration(Configuration.VERSION_2_3_26);
		freemarkerCfg.setServletContextForTemplateLoading(context, "/WEB-INF/templates/import");
		freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");
		freemarkerCfg.setDefaultEncoding("UTF-8");
		Template template = freemarkerCfg.getTemplate(name, "UTF-8");
		// 静态页面路径
		File htmlFile = new File(targetHtmlPath);
		Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
		// 模板数据替换并输出
		template.process(data, out);
		out.flush();
		out.close();
	}

	public boolean isEmpty(String value) {
		if (value == null || value.trim().length() == 0) {
			return true;
		}
		return false;
	}

	/**
	 * 对系统帮助的文章静态化
	 */
	public void helps() throws Exception {
		// 查询所有type为help的数据(t_news表)
		News param = new News();
		param.setType("help");// 通知：notice；帮助：help
		List<News> help = newsService.selectList(param);
		if (help == null || help.size() == 0) {
			logger.error("notices size = 0");
			return;
		}
		logger.error("notices size = " + help.size());

		HashMap<String, Object> data = new HashMap<String, Object>();
		for (int i = 0; i < help.size(); i++) {
			News news = help.get(i);
			if (StringUtils.isBlank(news.getContent())) {
				continue;
			}
			data.clear();
			data.put("e", news);// 路径： /templates/import/newsInfo.ftl
			String targetHtmlPath = RequestHolder.getSession().getServletContext().getRealPath("/") + "/WEB-INF/templates/jsp/helps/" + news.getId() + ".ftl";
			crateHTML(RequestHolder.getSession().getServletContext(), data, template_newsInfo, targetHtmlPath);
			logger.error("生成html页面成功！id=" + news.getId());
		}
	}

	/**
	 * 对新闻公告的文章静态化
	 */
	public void notices() throws Exception {
		News param = new News();
		param.setType("notice");
		List<News> notices = newsService.selectList(param);
		if (notices == null || notices.size() == 0) {
			logger.error("notices size = 0");
			return;
		}
		logger.error("notices size = " + notices.size());

		HashMap<String, Object> data = new HashMap<String, Object>();
		for (int i = 0; i < notices.size(); i++) {
			News news = notices.get(i);
			if (StringUtils.isBlank(news.getContent())) {
				continue;
			}

			data.clear();
			data.put("e", news);
			String templateHtml = RequestHolder.getSession().getServletContext().getRealPath("/") + "/WEB-INF/templates/jsp/notices/" + news.getId() + ".ftl";
			crateHTML(RequestHolder.getSession().getServletContext(), data, template_newsInfo, templateHtml);
			logger.error("生成html页面成功！id=" + news.getId());
		}
	}

	/**
	 * 对商品介绍静态化
	 * 
	 * @throws Exception
	 */
	public String products() throws Exception {
		List<Product> productList = productService.selectListProductHTML(new Product());
		if (productList == null || productList.size() == 0) {
			logger.error("productList size = 0");
			return null;
		}
		logger.error("productList size = " + productList.size());
		StringBuilder errorBuff = new StringBuilder();

		HashMap<String, Object> data = new HashMap<String, Object>();
		for (int i = 0; i < productList.size(); i++) {
			Product p = productList.get(i);
			if (StringUtils.isBlank(p.getProductHTML())) {
				continue;
			}

			data.clear();
			data.put("e", p);
			String templateHtml = RequestHolder.getSession().getServletContext().getRealPath("/") + "/WEB-INF/templates/jsp/product/" + p.getId() + ".ftl";
			try {
				crateHTML(RequestHolder.getSession().getServletContext(), data, template_product, templateHtml);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("生成html页面失败！id=" + p.getId());

				errorBuff.append(p.getId() + ",");
				continue;
			}
			logger.error("生成html页面成功！id=" + p.getId());
		}

		if (errorBuff.length() == 0) {
			return null;
		}
		return errorBuff.toString();
	}

	/**
	 * 静态化指定的商品
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	public String staticProductByID(String id) throws Exception {
		Product p = productService.selectById(id);
		if (p == null || StringUtils.isBlank(p.getProductHTML())) {
			logger.error("ERROR,not found product by id = " + id);
			throw new NullPointerException("ERROR,not found product by id = " + id);
		}

		HashMap<String, Object> data = new HashMap<String, Object>();
		data.clear();
		data.put("e", p);
		String templateHtml = RequestHolder.getSession().getServletContext().getRealPath("/") + "/WEB-INF/templates/jsp/product/" + p.getId() + ".ftl";
		crateHTML(RequestHolder.getSession().getServletContext(), data, template_product, templateHtml);
		logger.error("生成html页面成功！id=" + p.getId());

		return "success";
	}

	/**
	 * 静态化指定的文章
	 */
	public String staticNewsByID(String id) throws Exception {
		if (StringUtils.isBlank(id)) {
			throw new NullPointerException("id参数不能为空！");
		}

		News news = newsService.selectById(id);
		if (news == null || StringUtils.isBlank(news.getContent())) {
			logger.error("ERROR,not found news by id = " + id);
			throw new NullPointerException("ERROR,not found news by id = " + id);
		}

		HashMap<String, Object> data = new HashMap<String, Object>();
		data.clear();
		data.put("e", news);
		String templateHtml = null;

		if (news.getType().equals(News.news_type_help)) {
			templateHtml = RequestHolder.getSession().getServletContext().getRealPath("/") + "/WEB-INF/templates/jsp/helps/" + news.getId() + ".ftl";
		} else if (news.getType().equals(News.news_type_notice)) {
			templateHtml = RequestHolder.getSession().getServletContext().getRealPath("/") + "/WEB-INF/templates/jsp/notices/" + news.getId() + ".ftl";
		}
		// /zlkjeeShop_v4/src/main/webapp/newsInfo.ftl
		crateHTML(RequestHolder.getSession().getServletContext(), data, template_newsInfo, templateHtml);
		logger.error("生成html页面成功！id=" + news.getId());

		return "success";
	}
}
